/**	@file Fx.h 
 *	@brief 	Representation of general math functions by class Fx. */
#ifndef Fx_majdo_
#define Fx_majdo_
#include <string>
#include "Ex.h"
//#include "Expr.h"
namespace sympycpp {
class Expr;
/**     @class Fx 
 *      @brief Representation of general mathematical functions.
 *       
 *       Classes that represent particular mathematical functions have to be derived from this class. 
 *       These new "math functions" classes have to reimplement memeber functions copy, create, diff and 
 *       copy constructor. These changes ensures necessary functionality for inner functions, that need correct results
 *       of these functions for next computation.*/
class Fx: public Ex {
private:
	///	@brief  A name of represented function, that will used by comparative functions and output functions.
	std::string name_;
protected:
	///	@brief An expression that is the argument of the represented math function.
	Ex * e_;
public:
	/**	@brief Stealing constructor.
	 * 	Behaviour of this constructor is managed by a special memory management that is specified by the last parameter.
	 * 	@param e is an expression in the argument of constructed math function (its memory will be exploited)
	 * 	@param s is a name of constructed math function
	 * 	@param f is a flag of the non-standard memory management*/
	Fx(Ex * & e, const std::string & s, const allocationPolicy f);
	/**	@brief Standard constructor.
         *      @param e is a argument of constructed math function 
         *      @param s is a name of constructed math function */
	Fx(const Expr & e, const std::string & s);
	/**	@brief Standard constructor.
         *      @param e is a argument of constructed math function 
         *      @param s is a name of constructed math function */
	Fx(const Ex * e, const std::string & s);
        /**	@brief Standard copy constructor. */
	Fx(const Fx & x);
        /**	@brief Standard destructor.*/
	virtual ~Fx();
	/**	@brief Returns a name of represented math functions.*/
	std::string name()const;
	/**	@brief Special construction of new math functions.
	 * 	This function has a significance mainly for derived calasses as an available (reimplemented) interface,
	 * 	if construction of new mathematical functions is required. 
	 * 	This function should make special simplification for the particular math function and create new expression.   
	 * 	It is alternative to usual constructors, that need type information. The count of math functions
	 * 	is not fixed and therefore a code that can detect types for usual constructors is unreal thing. 
	 * 	Consequently, this function have to be reimpelemented by each derived class.
	 *	This class has a non-statdard memory managemant.
         *      @param e is a argument of constructed math function 
	 * 	@param f is a flag of the non-standard memory management*/
	virtual Ex * create(Ex * & e, const allocationPolicy f) const;
    	virtual size_t rsize(const bool all = true) const;
	virtual size_t asize() const;
	virtual size_t size() const;
	virtual std::string str() const;
        virtual std::string unsigned_str() const;
        virtual Ex * diff(const Sym & x) const;
	virtual std::string treeView(const int i) const;
	virtual Ex * copy()const;
	friend class ComparerIx;
	friend class Substitution;
	friend class Operations;
	friend class Utilities;
};
}
#endif
